

#pragma once
#include <winsock2.h>

class IocpPacket;
class IocpRecv
{
public :
	IocpRecv();
	virtual ~IocpRecv();
	
	BYTE* GetBuffer(int recvSize, int& fullsize);
	BYTE* GetBufferPrev();
	void SetBuffer(WSABUF*	pWsaBuf);
	bool CompletionRecv(int remain);

	WSABUF	m_ws;
	IocpPacket* m_pIocpPacket;
	IocpPacket* m_pIocpPacketPrev;
};

class SSession;
class IocpSend
{
public :
	IocpSend(SSession* pSession);
	~IocpSend();

	void Send(unsigned long type, BYTE* pPacket, const size_t& size);
	void OnSend(size_t size);
	void SetWaitSendComplete(const bool& bComplete, const int& postedSize=-1);
	void AddRelesePacketList(IocpPacket* pIocpPacket);
	void ReleseSendPacket();

	bool IsWaitComplete();
	int	GetWaittingCnt() const;
	int GetPostSendSize() const;
	void PostSendDirect();
	bool PostSendEach(BYTE* pPacket, const size_t& size);

	void Lock();
	void Unlock();

	bool m_bComplete;
	int m_waittingCnt;
	int m_postSendSize;

	IocpPacket* m_pFirstIocpPacket;
	IocpPacket* m_pNextIocpPacket;

	IocpPacket* m_pReleseIocpPacket;
	IocpPacket* m_pNextRelesePacket;
	SSession*	m_pSession;
	CriticalObj m_sendLock;
};

class IocpAccept
{
public:
#define NET_MAX_LISTENCON 50
	IocpAccept(SSession* pSession)
		:m_pParentSession(pSession){}
	~IocpAccept(){}

	bool Accept(const TCHAR* pIP, const int& port);
	bool ListenSock(const TCHAR* pIP, const int& port);
	void PostAcceptIOCP(const DWORD& dwAccpetSize);		
	void DestoryAccept();
	bool PostAccpet(SSession *pSession);	
	int ThreadAccept();	

	long GetCurrentAcceptSize() const {return m_CurrentAcceptSize;}
	void IncrementAcceptSize()	{::InterlockedIncrement( &m_CurrentAcceptSize );}
	void DecrementAcceptSize()	{::InterlockedDecrement( &m_CurrentAcceptSize );}	

	HANDLE m_hAcceptIOCP;
	HANDLE m_hAcceptThread;
	SOCKET m_acceptSocket;
	SOCKADDR_IN	m_acceptAddr;
	DWORD m_MaxAcceptSize;
	volatile long m_CurrentAcceptSize;
	SSession* m_pParentSession;
};
